#pragma once
#include<memory>
extern "C" {
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libavutil/pixdesc.h>
#include <libavutil/hwcontext.h>
#include <libavutil/opt.h>
#include <libavutil/avassert.h>
#include <libavutil/imgutils.h>
#include<libavutil/error.h>
}
#include"ThreadSafetyQueue.h"
#define fprintf(stderr,x) qDebug()<<x;
class DecodePipeLine
{
public:
	static DecodePipeLine* GetInstance();
	AVFrame* GetFrame();
	bool Decode(char* path);
	bool DecodeNet();
	int FrameQueSize();
	void PauseDecode();
	void RestartDecode();
	void Reset();
	bool DecodeFinnished();
	bool IsNet();
	bool SendDataToNetDecode(char* data);
private:
	DecodePipeLine();
	~DecodePipeLine();
	int PacketQueSize();
	bool InitDecoder(char* path);
	bool InitDecoderNet();
	void FileDemuxFunc();
	void FileDecodeFunc();
	void NetDecodeFunc();
private:
	ThreadSafeQueue<AVFrame*> frame_que_;
	ThreadSafeQueue<AVPacket*> pkt_que_;
	std::unique_ptr<std::thread> demux_thread_up_{ nullptr };
	std::unique_ptr<std::thread> decode_thread_up_{nullptr};
	std::atomic<bool> stop_{false};
	AVFormatContext* input_ctx_ = NULL;
	int video_stream{ false };
	AVStream* video_ = NULL;
	AVCodecContext* decoder_ctx_ = NULL;
	AVCodec* decoder_ = NULL;
	AVPacket* packet_{nullptr};
	AVFrame* frame_{ nullptr };
	std::atomic<bool> decode_thread_end_{false};
	std::atomic<bool> demux_thread_end_{ false };
	static DecodePipeLine* decodepipeline_p_;
	std::atomic<bool> reseting_{false};
	AVCodecParserContext* parser_{};
	std::unique_ptr<std::thread> decode_net_thread_up_{nullptr};
	std::unique_ptr<uint8_t, void(*)(uint8_t*)> net_inbuf_;
	uint8_t* net_data_{ nullptr };
	int net_data_size_{ };
	std::atomic<bool> is_net_{ false };
	std::atomic<bool> net_decode_end_{false};
	ThreadSafeQueue<char*> net_pkt_que_;
};

